﻿Imports WiremetModel.Entities.OEM
Imports WIREMET.DictionaryExtensions

Public Class OfertaView

    Private _unitOfWork As UnitOfWork
    Private _ofertaDictionary As Dictionary(Of Integer, Oferta)
    Private _detailsPanelWidth As Integer


    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        SetInitialFilter()
        RunFilter(CreateFilter())

        _detailsPanelWidth = sc_OfertaView.Panel2.Width
        ChangeDetailsPanelVisibility()
    End Sub


    Private Sub OfertaView_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub RefreshViewData()

        Dim ofertaRepository As New Repository(Of Oferta)(_unitOfWork)
        _ofertaDictionary = ofertaRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)

        Dim klientRepository As New Repository(Of Klient)(_unitOfWork)
        Dim klientList As IEnumerable(Of Klient) = klientRepository.GetAll()
        InitializeFilterComboBox(cmb_filter_NazwaFirmy, klientList)


        Dim statusOfertyRepository As New Repository(Of StatusOferty)(_unitOfWork)
        Dim statusOfertyList As IEnumerable(Of StatusOferty) = statusOfertyRepository.GetAll()
        InitializeFilterComboBox(cmb_filter_StatusOferty, statusOfertyList)

        Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)
        Dim gatunekList As IEnumerable(Of Gatunek) = gatunekRepository.GetAll()
        InitializeFilterComboBox(cmb_filter_Gatunek, gatunekList)

    End Sub


    Private Sub InitializeFilterComboBox(ByRef inputComboBox As ComboBox, ByVal data As IEnumerable(Of Object))

        inputComboBox.DataSource = New BindingSource(data, Nothing)
        inputComboBox.AutoCompleteCustomSource.Clear()
        inputComboBox.AutoCompleteCustomSource.AddRange(data.Select(Function(x) x.ToString()).ToArray())
        inputComboBox.SelectedIndex = -1

    End Sub

    Private Sub SetInitialFilter()
        dtp_DataRealizacjiPoczatkowa.Checked = True
        dtp_DataRealizacjiPoczatkowa.Value = DateTime.Today.AddMonths(-3).Date
    End Sub


    Private Sub RefreshOfertyTable(ByVal ofertyList As IEnumerable(Of Oferta))
        dgv_Oferty.Rows.Clear()
        Dim recordNumber As Integer = 1
        For Each oferta As Oferta In ofertyList
            Dim rowIndex As Integer = dgv_Oferty.Rows.Add(
                oferta.Id,
                recordNumber,
                oferta.Numer,
                oferta.Klient.NazwaSkrocona,
                oferta.DataOferty.ToShortDateString(),
                oferta.StatusOferty.Nazwa)
            recordNumber += 1

            Select Case oferta.StatusOferty.Id
                Case 1
                    dgv_Oferty.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightBlue 'lightskyblue
                Case 2
                    dgv_Oferty.Rows(rowIndex).DefaultCellStyle.BackColor = Color.Moccasin
                Case 3
                    dgv_Oferty.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightGreen
                Case 4
                    dgv_Oferty.Rows(rowIndex).DefaultCellStyle.BackColor = Color.Salmon
            End Select
        Next
    End Sub


#Region "Filter"

    Private Structure Filter
        Public numerOferty As String
        Public klientId As Integer?
        Public dateStart As Date?
        Public dateEnd As Date?
        Public gatunekId As Integer?
        Public wymiar As String
        Public statusOfertyId As Integer?
    End Structure


    Private Function CreateFilter() As Filter
        Return New Filter With
        {
            .numerOferty = txt_filter_NumerOferty.Text.Trim(),
            .klientId = If(IsNothing(cmb_filter_NazwaFirmy.SelectedItem), CType(Nothing, Integer?), CType(cmb_filter_NazwaFirmy.SelectedItem, Klient).Id),
            .dateStart = If(dtp_DataRealizacjiPoczatkowa.Checked, dtp_DataRealizacjiPoczatkowa.Value.Date, CType(Nothing, Date?)),
            .dateEnd = If(dtp_DataRealizacjiKoncowa.Checked, dtp_DataRealizacjiKoncowa.Value.Date, CType(Nothing, Date?)),
            .gatunekId = If(IsNothing(cmb_filter_Gatunek.SelectedItem), CType(Nothing, Integer?), CType(cmb_filter_Gatunek.SelectedItem, Gatunek).Id),
            .statusOfertyId = If(IsNothing(cmb_filter_StatusOferty.SelectedItem), CType(Nothing, Integer?), CType(cmb_filter_StatusOferty.SelectedItem, StatusOferty).Id),
            .wymiar = txt_filter_Wymiar.Text.Trim()
        }
    End Function

    Private Function IsOfertaSatisfiedByFilter(ByVal oferta As Oferta, ByVal filter As Filter) As Boolean

        Return oferta.Numer.StartsWith(filter.numerOferty, StringComparison.CurrentCultureIgnoreCase) AndAlso
            (Not filter.klientId.HasValue OrElse oferta.Klient.Id = filter.klientId.Value) AndAlso
            (Not filter.dateStart.HasValue OrElse oferta.DataOferty >= filter.dateStart.Value) AndAlso
            (Not filter.dateEnd.HasValue OrElse oferta.DataOferty <= filter.dateEnd.Value) AndAlso
            (Not filter.gatunekId.HasValue OrElse oferta.PozycjeOferty.Any(Function(x) x.Gatunek.Id = filter.gatunekId.Value)) AndAlso
            (String.IsNullOrEmpty(filter.wymiar) OrElse oferta.PozycjeOferty.Where(Function(x) x.Wymiar.StartsWith(filter.wymiar, StringComparison.CurrentCultureIgnoreCase)).Any()) AndAlso
            (Not filter.statusOfertyId.HasValue OrElse oferta.StatusOferty.Id = filter.statusOfertyId.Value)
    End Function


    Private Sub RunFilter(ByVal filter As Filter)

        Dim filteredOferty As New List(Of Oferta)

        For Each oferta As Oferta In _ofertaDictionary.Values
            If IsOfertaSatisfiedByFilter(oferta, filter) Then
                filteredOferty.Add(oferta)
            End If
        Next

        dgv_Oferty.Rows.Clear()
        RefreshOfertyTable(filteredOferty.OrderByDescending(Function(x) x.DataOferty))

        ComboBoxCleanupWhenNoValueSelected(cmb_filter_NazwaFirmy)
        ComboBoxCleanupWhenNoValueSelected(cmb_filter_StatusOferty)
        ComboBoxCleanupWhenNoValueSelected(cmb_filter_Gatunek)

    End Sub

    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        txt_filter_NumerOferty.Text = String.Empty
        cmb_filter_NazwaFirmy.ResetText()
        cmb_filter_NazwaFirmy.SelectedIndex = -1
        dtp_DataRealizacjiKoncowa.Checked = False
        dtp_DataRealizacjiPoczatkowa.Checked = False
        cmb_filter_StatusOferty.ResetText()
        cmb_filter_StatusOferty.SelectedIndex = -1
        cmb_filter_Gatunek.ResetText()
        cmb_filter_Gatunek.SelectedIndex = -1
        txt_filter_Wymiar.Text = String.Empty
        
    End Sub


    Private Sub btn_RunFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter(CreateFilter())
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter(CreateFilter())
    End Sub

    Private Sub filterInput_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles txt_filter_NumerOferty.KeyDown, txt_filter_Wymiar.KeyDown, cmb_filter_Gatunek.KeyDown, cmb_filter_NazwaFirmy.KeyDown, cmb_filter_StatusOferty.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(CreateFilter())
        End If
    End Sub


#End Region


    Private Sub RefreshDetailsPozycjeOfertyTable(ByVal pozycjeOfertyList As IEnumerable(Of PozycjaOferty))
        dgv_PozycjeOferty.Rows.Clear()
        Dim recordNumber As Integer = 1
        For Each pozycjaOferty As PozycjaOferty In pozycjeOfertyList
            Dim ilosc As Decimal
            Decimal.TryParse(pozycjaOferty.Ilosc, ilosc)
            dgv_PozycjeOferty.Rows.Add(
                pozycjaOferty.Id,
                recordNumber,
                pozycjaOferty.Wymiar,
                pozycjaOferty.Gatunek.NazwaAng,
                pozycjaOferty.Ilosc.ToString() + " " + pozycjaOferty.JednostkaMiary.Jednostka,
                pozycjaOferty.Cena.ToString() + " " + pozycjaOferty.Waluta.Nazwa,
                (ilosc * pozycjaOferty.Cena).ToString() + " " + pozycjaOferty.Waluta.Nazwa)
            recordNumber += 1
        Next
    End Sub


    Private Sub RefreshDetails(ByVal oferta As Oferta)

        Dim totalCost As Decimal = 0
        Dim waluta As String = String.Empty
        For Each pozycjaOferty As PozycjaOferty In oferta.PozycjeOferty
            Dim ilosc As Decimal
            Decimal.TryParse(pozycjaOferty.Ilosc, ilosc)
            totalCost += ilosc * CType(pozycjaOferty.Cena, Decimal)
            waluta = pozycjaOferty.Waluta.Nazwa
        Next

        txt_TotalCost.Text = totalCost.ToString() + " " + waluta

        txt_Email.Text = If(oferta.Email Is Nothing OrElse oferta.Email.Id = -1, oferta.Klient.Email + " (klient)", oferta.Email.EmailAddress)
        txt_DataWaznosci.Text = oferta.DataWaznosci.ToShortDateString() + "   pozostało: " + (oferta.DataWaznosci - Date.Now).Days.ToString() + " dni"
        txt_CzasRealizacji.Text = oferta.CzasRealizacji.ToString()
        txt_Uwagi.Text = oferta.Uwagi
        'gb_Details.Text = "SZCZEGÓŁY ZLECENIA - " + wysylka.Zlecenie.Numer
        RefreshDetailsPozycjeOfertyTable(oferta.PozycjeOferty.OrderBy(Function(x) x.Wymiar))
    End Sub

    Private Sub RefreshDetails()
        If Not sc_OfertaView.Panel2Collapsed AndAlso Not dgv_Oferty.SelectedRows.Count = 0 Then
            Dim ofertaId As Integer = CInt(dgv_Oferty.SelectedRows(0).Cells("OfertaId").Value)
            RefreshDetails(_ofertaDictionary(ofertaId))
        Else
            gb_Details.Text = "SZCZEGÓŁY ZLECENIA"
        End If
    End Sub

    Private Sub dgv_Oferty_SelectionChanged(ByVal sender As System.Object, ByVal e As EventArgs) Handles dgv_Oferty.SelectionChanged
        RefreshDetails()
    End Sub

    Private Function GetSelectedOferta() As Oferta
        Return _ofertaDictionary(CInt(dgv_Oferty.SelectedRows(0).Cells("OfertaId").Value))
    End Function


    Private Sub EnsureOfertaIsSelected()
        If dgv_Oferty.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz ofertę, aby kontynuować.")
        End If
    End Sub


    Private Sub dgv_Oferty_CellMouseDoubleClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs) Handles dgv_Oferty.CellMouseDoubleClick
        Try
            EnsureOfertaIsSelected()
            Dim selectedOferta As Oferta = GetSelectedOferta()
            Dim ofertaForm As New frmOferty(selectedOferta.Id, False)
            'ofertaForm.MdiParent = MdiParent
            ofertaForm.TopMost = True
            ofertaForm.ShowDialog()
            Cursor = Cursors.WaitCursor
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub


#Region "Actions"

    Private Sub ts_btn_New_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_New.Click
        Try
            Dim ofertaForm As New frmOferty(0, False)
            ofertaForm.MdiParent = MdiParent
            ofertaForm.Show()
            'ofertaForm.TopMost = True
            'ofertaForm.ShowDialog()
            Cursor = Cursors.WaitCursor
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_Edit_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Edit.Click
        Try
            EnsureOfertaIsSelected()
            Dim selectedOferta As Oferta = GetSelectedOferta()
            Dim ofertaForm As New frmOferty(selectedOferta.Id, False)
            ofertaForm.MdiParent = MdiParent
            'ofertaForm.TopMost = True
            'ofertaForm.ShowDialog()
            ofertaForm.Show()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_Copy_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Copy.Click
        Try
            EnsureOfertaIsSelected()
            Dim selectedOferta As Oferta = GetSelectedOferta()
            Dim ofertaForm As New frmOferty(selectedOferta.Id, True)
            ofertaForm.MdiParent = MdiParent
            'ofertaForm.TopMost = True
            'ofertaForm.ShowDialog()
            ofertaForm.Show()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_Zlecenie_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Zlecenie.Click
        Try
            EnsureOfertaIsSelected()
            Dim selectedOferta As Oferta = GetSelectedOferta()
            If selectedOferta.StatusOferty.Nazwa = "nowa" Then
                Throw New Exception("Proszę, wyślij ofertę przed utworzeniem zlecenia.")
            End If

            Dim zleceniaForm As New frmZlecenia(selectedOferta.Id, 3)
            zleceniaForm.MdiParent = MdiParent
            zleceniaForm.Show()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
    End Sub

    Private Sub RefreshView()
        Dim filter As Filter = CreateFilter()
        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        'ClearFilter()
        'SetInitialFilter()
        RunFilter(filter)
    End Sub

    Private Sub ts_btn_RefreshView_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        RefreshView()
    End Sub

    Private Sub ChangeDetailsPanelVisibility()
        If sc_OfertaView.Panel2Collapsed Then
            sc_OfertaView.Panel2Collapsed = False
            Me.Width += _detailsPanelWidth + sc_OfertaView.SplitterWidth
        Else
            _detailsPanelWidth = sc_OfertaView.Panel2.Width
            Me.Width -= _detailsPanelWidth + sc_OfertaView.SplitterWidth
            sc_OfertaView.Panel2Collapsed = True
        End If
        Refresh()
    End Sub

    Private Sub ts_btn_Details_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_Details.Click
        ChangeDetailsPanelVisibility()
        RefreshDetails()
    End Sub

#End Region

End Class